﻿using System;
using System.Collections.Generic;
using Core.Base.Module;
using Core.Singleton;
using Global.Module;

namespace Core.Mgr
{
    /// <summary>
    /// Module管理类
    /// </summary>
    public class ModuleMgr : Singleton<ModuleMgr>
    {
        private Dictionary<Type, BaseModule> modules = new Dictionary<Type, BaseModule>();

        public virtual void OnInit()
        {
            RegModule<GlobalModule>();
        }

        public virtual void OnDestroy()
        {
            foreach (var item in modules.Values)
            {
                item.OnDestroy();
            }

            modules.Clear();
        }


        /// <summary>
        /// 注册
        /// </summary>
        public TM RegModule<TM>() where TM : BaseModule
        {
            Type type = typeof(TM);
            TM module = default;
            if (!modules.ContainsKey(type))
            {
                module = Activator.CreateInstance(type, true) as TM;
                modules.Add(type, module);
                module.OnInit();
            }

            return module;
        }

        /// <summary>
        /// 卸载
        /// </summary>
        public void UnRegModule<TM>() where TM : BaseModule
        {
            Type type = typeof(TM);
            if (modules.TryGetValue(type, out BaseModule module))
            {
                module.OnDestroy();
                modules.Remove(type);
            }
        }

        public void UnRegModule(BaseModule module)
        {
            Type type = module.GetType();
            object[] attributes = type.GetCustomAttributes(typeof(ModuleAttribute), false);
            ModuleAttribute moduleAttribute = attributes[0] as ModuleAttribute;
            if (moduleAttribute.IsResident)
                return;

            foreach (var item in modules.Keys)
            {
                BaseModule curModule = modules[item];
                if (curModule == module)
                {
                    type = item;
                    break;
                }
            }

            if (type != null)
            {
                module.OnDestroy();
                modules.Remove(type);
            }
        }

        public TM RetrieveModule<TM>() where TM : BaseModule
        {
            TM ret = default;
            Type type = typeof(TM);
            if (modules.TryGetValue(type, out BaseModule module))
            {
                ret = module as TM;
            }

            return ret;
        }
    }
}